<script setup>
import { ref, reactive, getCurrentInstance, defineModel, onMounted, watch, nextTick, h, markRaw, toRaw, onBeforeUnmount } from "vue";
import { ArrowLeftBold, ArrowRightBold } from '@element-plus/icons-vue'
import { queryArray } from "@/utils"

const props = defineProps({
  data: {
    type: Array,
    default: []
  },
  modelValue: {
    type: Array,
    default: () => []
  }
})
//定义emit
const emit = defineEmits(['update:modelValue'])

const treeAllData = reactive({
  oldData: [],
  newData: []
})

const leftData = ref([])           // 左边数据 
const rightData = ref([])           // 右边数据 

const checkAllLeft = ref(false);    // 左边全选
const checkAllRight = ref(false);   // 右边边全选

const leftTree = ref(null)          // 左边树DOM
const rightTree = ref(null)         // 右边树DOM

const selectedDataLeft = ref([]);       // 左边选中的数据
const selectedDataRight = ref([]);      // 右边选中的数据

function initTreeData() {
  treeAllData.oldData = {
    
  }
  let allNode = JSON.parse(JSON.stringify(props.data))
  let checked = JSON.parse(JSON.stringify(props.modelValue))
  console.log(props, '数据');
  leftData.value = delTree(allNode, checked)
  rightData.value = checked
}


function delTree(allTreeData, delArr){
  let arr = []
  allTreeData.forEach(i => {
    let show = delArr.some(j => j.key == i.key)
    i.children && (i.children = delTree(i.children, delArr))
    !show && arr.push(i)
  })
  return arr
}
// 阻止二次触发
let timerTwo = null;
let preventShow = true;
function leftTreeChange(data, checked, indeterminate) {
	if(!preventShow) return;
	preventShow = false;
	timerTwo = setTimeout(() => {
		preventShow = true;
	}, 300);
  setLeftCheckData();
};
function rightCheckChange(val, item) {
  if (val) {
    selectedDataRight.value.push(item)
  }else{
    let _index = selectedDataRight.value.findIndex(i => i.key == item.key);
    selectedDataRight.value.splice(_index, 1)
  }
}

function setLeftCheckData(){
  let selectedData = leftTree.value.getCheckedNodes()
  selectedDataLeft.value = queryArray(getOrganData(selectedData), 'value')
}

function getOrganData(treeData){
  let arr = [];
  treeData.forEach(i => {
    if (i.zoom == 3) {
      arr.push(i)
    } else {
      let children = getOrganData(i.children)
      arr = [...arr, ...children]
    }
  })
  return arr;
}

function checkAllChange(type, val){
  if (type == 'left') {
    if (val) {
      leftTree.value.setCheckedNodes(props.data)
    }else{
      leftTree.value.setCheckedNodes([]);
    }
  } else {

  }
}

function rightBtnClick(){
  let checkData = selectedDataLeft.value.map(i => {
    i['checkValue'] = false;
    return i
  })
  emit('update:modelValue', [...checkData])
}
function leftBtnClick(){
  selectedDataRight.value = []
  let checkData = props.modelValue.filter(i => !i.checkValue)
  emit('update:modelValue', [...checkData])
}

// 监听 data 和 value 的变化  
watch([() => props.data, () => props.modelValue], () => {
  initTreeData();  
}, { immediate: true });  
</script>

<template>
  <div class='tree-transfer'>
    <div class="tree-panel">
      <div class="tree-panel-header">
        <el-checkbox v-model="checkAllLeft" @change="(val) => checkAllChange('left', val)" :indeterminate="!!selectedDataLeft.length" label="list1" size="large" />
        <span class="panel-length">0/15</span>
      </div>
      <div class="tree-panel-body">
        <el-tree
          ref="leftTree"
          node-key="key"
          :data="leftData"
          show-checkbox
          @check-change="leftTreeChange"
        />
      </div>
    </div>
    <div class="tree-transfer_bottons">
      <div class="btns_tree">
        <el-button type="primary" :disabled="!selectedDataRight.length" :icon="ArrowLeftBold" @click="leftBtnClick" />
        <el-button type="primary" :disabled="!selectedDataLeft.length" :icon="ArrowRightBold" @click="rightBtnClick" />
      </div>
    </div>
    <div class="tree-panel">
      <div class="tree-panel-header">
        <el-checkbox v-model="checkAllRight" label="list2" size="large" />
        <span class="panel-length">0/15</span>
      </div>
      <div class="tree-panel-body">
        <div class="check-list">
          <div class="check-item" v-for="item in rightData" :key="item.value"><el-checkbox @change="(val, e) => rightCheckChange(val, item)" v-model="item.checkValue" :label="item.label" /></div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="less">
.tree-transfer{
  font-size: 14px;
  width: fit-content;
  margin: 0 auto;
  padding: 30px;
  background-color: #fafafa;
  display: flex;
  .tree-panel{
    overflow: hidden;
    background: #fff;
    display: inline-block;
    text-align: left;
    vertical-align: middle;
    width: 240px;
    max-height: 100%;
    .tree-panel-body{
      height: 320px;
      border-left: 1px solid #ebeef5;
      border-right: 1px solid #ebeef5;
      border-bottom: 1px solid #ebeef5;
      border-bottom-left-radius: 4px;
      border-bottom-right-radius: 4px;
      padding: 10px 0;
      overflow: auto;
      .check-list{
        padding: 0 10px;
      }
    }
    .tree-panel-header{
      position: relative;
      height: 40px;
      display: flex;
      align-items: center;
      background-color: #f5f7fa;
      margin: 0;
      padding-left: 15px;
      border: 1px solid #ebeef5;
      border-top-left-radius: 4px;
      border-top-right-radius: 4px;
      color: #000;
      .panel-length{
        position: absolute;
        right: 15px;
        top: 50%;
        transform: translate3d(0,-50%,0);
        color: var(--el-text-color-secondary);
        font-size: 12px;
        font-weight: 400;
      }
    }
  }
  .tree-transfer_bottons{
    position: relative;
    padding: 0 15px;
    height: 100%;
    .btns_tree{
      display: flex;
      margin-top: 160px;
    }
  }
}
</style>